﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using HAVNet.Core.LitJson;

namespace pmf
{
    public partial class FrmMain : Form
    {
        string _carpetaFuente = string.Empty;

        public FrmMain()
        {
            InitializeComponent();
            
            txtCarpetaBase.Text         = Program.config.carpetaBase;
            Width                       = Program.config.frmMainWidth;
            Height                      = Program.config.frmMainHeight;
            WindowState                 = (FormWindowState) Program.config.frmMainWindowState;

            FormClosing                 += new FormClosingEventHandler(FrmMain_FormClosing);
            Load                        += new EventHandler(FrmMain_Load);
            txtCarpetaBase.TextChanged  += new EventHandler(txtCarpetaBase_TextChanged);
            btnBuscarCarpetaBase.Click  += new EventHandler(btnBuscarCarpetaBase_Click);
            btnSiguiente.Click          += new EventHandler(btnSiguiente_Click);
        }

        void btnSiguiente_Click(object sender, EventArgs e)
        {
            try
            {
                string [] partesInfoArchivo = validarTexto(txtTextoMail.Text);

                // ok, esta todo bien, hora de copiar archivos...
                using (FrmCopia frmCopia = 
                    new FrmCopia(partesInfoArchivo, txtTextoMail.Text, _carpetaFuente))
                    frmCopia.ShowDialog();
            }
            catch (Exception exx)
            {
                MessageBox.Show(
                    exx.Message, 
                    Application.ProductName, 
                    MessageBoxButtons.OK, 
                    MessageBoxIcon.Error
                );
            }
        }

        void FrmMain_Load(object sender, EventArgs e)
        {
            Left= Program.config.frmMainLeft;
            Top = Program.config.frmMainTop;
            txtTextoMail.Select();
        }

        void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            Program.config.frmMainLeft = Left;
            Program.config.frmMainTop = Top;
            Program.config.frmMainWidth = Width;
            Program.config.frmMainHeight = Height;
            Program.config.frmMainWindowState = (int)WindowState;
        }

        void btnBuscarCarpetaBase_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog dirDialog = new FolderBrowserDialog())
            {
                dirDialog.Description = "La carpeta \"base\" es la carpeta que contiene a TODAS las otras carpetas que contienen las fotos";
                //dirDialog.ShowNewFolderButton = true;

                if (Directory.Exists(txtCarpetaBase.Text))
                    dirDialog.SelectedPath = txtCarpetaBase.Text;
                else
                    dirDialog.RootFolder = Environment.SpecialFolder.MyComputer;

                if (dirDialog.ShowDialog(this) == DialogResult.OK)
                    txtCarpetaBase.Text = dirDialog.SelectedPath;
            }
        }

        void txtCarpetaBase_TextChanged(object sender, EventArgs e)
        {
            Program.config.carpetaBase = txtCarpetaBase.Text;
        }

        string[] validarTexto(string texto)
        {
            string[] partes = texto.Split(
                new char[] { '\r', '\n' },
                StringSplitOptions.RemoveEmptyEntries
            );

            string carpetaRelativa = string.Empty;
            string listadoArchivos = string.Empty;

            if (partes.Length != 8)
                throw new Exception("Faltan o sobran partes en el texto");

            // carpeta fuente (base + relativa)
            carpetaRelativa = partes[partes.Length - 2];
            carpetaRelativa = carpetaRelativa.Replace('/', '\\');
            _carpetaFuente = Path.Combine(txtCarpetaBase.Text, carpetaRelativa);

            if (! Directory.Exists(_carpetaFuente))
                throw new Exception(string.Format("No existe la carpeta '{0}'", _carpetaFuente));

            // ok, ahora verifico las partes de los archivos
            listadoArchivos = partes[partes.Length - 1];

            string[] partesInfoArchivo = listadoArchivos.Split(
                new char [] { '|', ' ' }, 
                StringSplitOptions.RemoveEmptyEntries
            );

            verificarParteInfoArchivo(partesInfoArchivo);

            return partesInfoArchivo;
        }

        static void verificarParteInfoArchivo(string [] partesInfoArchivo)
        {
            // "Archivo:"
            // "IMG_3876.JPG"
            // "Cantidad:"
            // "3"
            // "Archivo:"
            // "IMG_3877.JPG"
            // "Cantidad:"
            // "5"
            // .
            // .
            // .

            // me fijo que las partes sean múltiplo de 4 y que haya por lo menos 4
            if ((partesInfoArchivo == null) ||
                (partesInfoArchivo.Length == 0) ||
                (partesInfoArchivo.Length % 4 != 0))
                throw new Exception("La parte de archivos no está bien formada");
            
            // solo me fijo que concuerden los títulos para ver si esta bien formado
            for (int i = 0; i < partesInfoArchivo.Length; i += 4)
            {
                string error = string.Format("El elemento {0} no está bien formado", (i / 4) + 1);

                // me fijo si existe el título "Archivo:"
                if (partesInfoArchivo[i + 0] != "Archivo:")
                    throw new Exception(error);

                // me fijo si el archivo corresponde a un nombre de archivo válido...
                if (partesInfoArchivo[i + 1]
                    .IndexOfAny(Path.GetInvalidFileNameChars()) != -1)
                    throw new Exception(error);

                // me fijo si existe el título "Cantidad:"
                if (partesInfoArchivo[i + 2] != "Cantidad:")
                    throw new Exception(error);

                // me fijo si la cantidad es un número
                foreach (char c in partesInfoArchivo[i + 3])
                    if ((c < '0') || (c > '9'))
                        throw new Exception(error);
            }
        }
    }
}
